﻿using Share.Services;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.Json;


namespace Share;
/// <summary>
/// 通用请求参数，所有API都有
/// </summary>
/// <typeparam name="T">业务参数字段，暂时以 IcbcApiRequest 作为基类，只有一个URL属性，
/// 每个接口的 biz_content 字段创建一个类，并继承 IcbcApiRequest
/// </typeparam>
public class RequestBase<T>(T bizContent, ApiSetting setting) where T : IcbcApiRequest
{
    public string ApiAddress => _bizContent.Url;

    [DataMember(Name = "app_id")] public string AppId { get; set; } = setting.AppId;
    [DataMember(Name = "msg_id")] public string MsgId { get; set; } = UtilitiesService.GetFSeqNo();
    [DataMember(Name = "format")] public string Format => "json";//请求参数格式，仅支持json 
    [DataMember(Name = "charset")] public string Charset => "UTF-8";
    [DataMember(Name = "encrypt_type")] public string? EncryptType { get; set; }
    [DataMember(Name = "sign_type")] public string SignType { get; set; } = setting.SignType;
    [DataMember(Name = "sign")] public string Sign { get; set; } = string.Empty;

    [DataMember(Name = "timestamp")] public string Timestamp { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
    [DataMember(Name = "ca")] public string? CA { get; set; } = setting.CA;

    [DataMember(Name = "biz_content")]
    public string BizContent
    {
        get => JsonSerializer.Serialize(_bizContent);
    }

    private T _bizContent = bizContent;

}

public static class RequestBaseExtensions
{
    public static IEnumerable<KeyValuePair<string, string>> GetPostValues<T>(this RequestBase<T> request) where T : IcbcApiRequest
    {
        var keyValuePairs = new List<KeyValuePair<string, string>>();
        var properties = typeof(RequestBase<T>).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (var property in properties)
        {
            var propertyNameAttribute = property.GetCustomAttribute<DataMemberAttribute>();
            if (propertyNameAttribute != null)
            {
                var key = propertyNameAttribute?.Name ?? property.Name;
                var value = property.GetValue(request)?.ToString() ?? string.Empty;
                if (!string.IsNullOrEmpty(value))
                {
                    keyValuePairs.Add(new KeyValuePair<string, string>(key, value));
                }
            }
        }
        return keyValuePairs;
    }

    public static string GetToSignString<T>(this RequestBase<T> request) where T : IcbcApiRequest
    {
        var keyValuePairs = request.GetPostValues();

        return $"/{request.ApiAddress}?{string.Join("&", keyValuePairs
            .Where(kvp => kvp.Key != "sign")
            .OrderBy(kvp => kvp.Key) // !!按字段名称排序!!
            .Select(kvp => $"{kvp.Key}={kvp.Value}"))}";
    }
}